package com.atguigu.gmall.rabbit.service;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.rabbit.entity.GmallCorrelationData;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;

import javax.annotation.Resource;
import java.util.Date;
import java.util.UUID;

@Component
public class RabbitService {

    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private RedisTemplate redisTemplate;

    //发送普通消息
    public boolean sendMessage(String exchange,String routingKey,Object msg){
        GmallCorrelationData correlationData = retryMessageData(exchange, routingKey, msg);
        //rabbitTemplate进行转换并发送
        rabbitTemplate.convertAndSend(exchange,routingKey,msg,correlationData);
        return true;
    }

    //发送死信延迟消息
    public void sendDeadLetterMessage(String exchange,String routingKey,Object msg,int delayTime){
        GmallCorrelationData correlationData = retryMessageData(exchange, routingKey, msg);
        //是延迟消息
        correlationData.setDelay(true);
        //延迟的时间
        correlationData.setDelayTime(delayTime);
        //延迟消息  交换机，routingkey，信息，延迟时间，相关数据
        rabbitTemplate.convertAndSend(exchange,routingKey,msg,message -> {
            //设置过期时间，基于死信
            System.out.println("发送消息的时间："+ new Date());
            message.getMessageProperties().setExpiration(String.valueOf(delayTime*1000));//TTL  字符串类型，单位毫秒
            return message;
        },correlationData);
    }

    //发送延迟（基于插件实现）
    public void sendDelayMessage(String exchange,String routingKey,Object msg,int delayTime) {
        GmallCorrelationData correlationData = retryMessageData(exchange, routingKey, msg);
        //是延迟消息
        correlationData.setDelay(true);
        //延迟的时间
        correlationData.setDelayTime(delayTime);
        //延迟消息  交换机，routingkey，信息，延迟时间，相关数据
        rabbitTemplate.convertAndSend(exchange, routingKey, msg, message -> {
            //设置延迟时间，基于插件
            System.out.println("发送消息的时间：" + new Date());
            message.getMessageProperties().setDelay(delayTime*1000);//TTL  字符串类型，单位毫秒
            return message;
        }, correlationData);
    }

    private GmallCorrelationData retryMessageData(String exchange, String routingKey, Object msg) {
        //重新发送时的应答对象，保存交换机 routingKey Msg
        //专为失败重新发送消息携带信息使用
        GmallCorrelationData correlationData = new GmallCorrelationData();
        String uuid = UUID.randomUUID().toString();
        correlationData.setId(uuid);
        correlationData.setExchange(exchange);
        correlationData.setRoutingKey(routingKey);
        correlationData.setMessage(msg);

        redisTemplate.opsForHash().put("rabbit_prefix",uuid, JSONObject.toJSONString(correlationData));
        return correlationData;
    }
}
